package kibahed.university.effizientealgorithmen.abstractclasses;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import kibahed.university.effizientealgorithmen.interfaces.IEdge;
import kibahed.university.effizientealgorithmen.interfaces.IGraph;
import kibahed.university.effizientealgorithmen.interfaces.IVertex;

/**
 * 
 * @author Bernhard Kinast
 * @author Daniel Heily
 * 
 */

public abstract class AGraph implements IGraph {

	boolean[][] adjecancyMatrix = null;
	List<IVertex> vertexesAsList = new ArrayList<IVertex>();
	IVertex[] vertexes = null;
	private IEdge[] path = null;
	private int[] nodeTour = null;
	private double[][] costMatrix = null;
	private Set<IEdge> edges = null;

	StringBuilder builder = new StringBuilder();
	private String tspName;

	@Override
	public IVertex[] getVertexes() {
		if (vertexes == null) {
			vertexes = new IVertex[vertexesAsList.size()];
			for (int i = 0; i < vertexes.length; i++) {
				vertexes[i] = vertexesAsList.get(i);
			}
		}
		return vertexes;
	}

	@Override
	public boolean[][] getAdjecencyMatrix() {
		return adjecancyMatrix;
	}

	public void addVertex(IVertex vertex) {
		vertexes = null;
		vertexesAsList.add(vertex);
	}

	protected void calculateAdjecencyMatrix() {
		adjecancyMatrix = new boolean[vertexes.length][vertexes.length];
		for (int i = 0; i < vertexes.length; i++) {
			for (int j = 0; j < vertexes.length; j++) {
				IVertex vertex = vertexes[i];
				for (IEdge edge : vertex.getEdges()) {
					if (edge.getEnd() == j) {
						adjecancyMatrix[i][j] = true;
					}
				}
			}
		}
	}

	public void setCostMatrix(double[][] costMatrix) {
		this.costMatrix = costMatrix;
	}

	public double[][] getCostMatrix() {
		return costMatrix;
	}

	public void showAdjecencyMatrix() {

		for (int i = 0; i < adjecancyMatrix.length; i++) {
			for (int j = 0; j < adjecancyMatrix[0].length; j++) {
				if (adjecancyMatrix[i][j]) {
					System.out.print("\t1");
				} else {
					System.out.print("\t0");
				}
			}
			System.out.println();
		}

	}

	public void setEdgeTour(IEdge[] path) {
		this.path = path;
	}

	public IEdge[] getEdgeTour() {
		return path;
	}

	public int[] getNodeTour() {
		return nodeTour;

	}

	public void setNodeTour(int[] nodeTour) {
		this.nodeTour = nodeTour;
	}

	public void setEdges(Set<IEdge> edges) {
		this.edges = edges;
	}

	public Set<IEdge> getEdges() {
		return edges;
	}

	public void addMessages(String string) {
		builder.append(string).append("\n");
	}

	public String getMessages() {
		return builder.toString();

	}

	public void clearMessages() {
		builder = new StringBuilder();
	}

	public IVertex getVertexForEdge(IEdge edge) {
		IVertex vertex = null;
		for (IVertex v : vertexes) {
			if (v.hasEdge(edge)) {
				vertex = v;
				break;
			}
		}
		return vertex;
	}

	public IEdge getEdgeBetweenVertices(int id, int id2) {

		for (IEdge e : edges) {
			
			if (e.getStart() == id && e.getEnd() == id2) {
//				System.out.println("FOUND FITTING EDGE");
				return e;
			}
			
		}
	
		return null;
	}
	
	public void setTspName(String tspName) {
		this.tspName = tspName;
	}
	
	public String getTspName() {
		return tspName;
	}
}
